﻿using System;
using System.Collections.Generic;
using System.Text;

using Galaxy.ModuleInterface;
using Galaxy.ModuleInterface.Events;

using Galaxy.Core.Exceptions;

namespace Galaxy.Core.Events
{
    /// <summary>Обработчик событий ядра</summary>
    /// <param name="Core">Ядро</param>
    /// <param name="Arg">Аргументы события</param>
    public delegate void GalaxyCoreEventHandler(CGalaxyCore Core, GalaxyCoreEventArgs Arg);
    /// <summary>Обработчик события запуска</summary>
    /// <param name="Core">Запускаемое ядро</param>
    /// <param name="Arg">Аргументы события запуска</param>
    public delegate void OnEnableEventHandler(CGalaxyCore Core, OnEnableEventArgs Arg);
    /// <summary>Аргументы события ошибки ядра</summary>
    /// <param name="Core">Ядро, породившее ошибку</param>
    /// <param name="Arg">Аргументы события ошибки</param>
    public delegate void OnErrorEventHandler(CGalaxyCore Core, OnErrorEventArgs Arg);

    /* --------------------------------------------------------------------------- */

    /// <summary>Аргументы событий ядра</summary>
    public class GalaxyCoreEventArgs : GalaxyModuleEventArgs { }

    /// <summary>Аргументы события запуска ядра</summary>
    public class OnEnableEventArgs : GalaxyCoreEventArgs
    {
        /// <summary>Зfпущенное ядро</summary>
        private CGalaxyCore fCore;

        /// <summary>Текущее состояние ядра</summary>
        public bool Enable
        {
            get { return fCore.Enable; }
            set { fCore.Enable = value; }
        }

        /// <summary>Инициализация аргумента события запуска ядра</summary>
        /// <param name="Core">Ядро</param>
        public OnEnableEventArgs(CGalaxyCore Core) { fCore = Core; }
    }

    /// <summary>Аргументы события ошибки в ядре</summary>
    public class OnErrorEventArgs : GalaxyCoreEventArgs
    {
        /// <summary>Ошибка, произощедшая в ядре</summary>
        private GalaxyCoreException f_Error;

        /// <summary>Исключительная ситуация ядра</summary>
        public GalaxyCoreException Error { get { return f_Error; } }

        /// <summary>Инициализация нового экземпляра аргумента события ошибки ядра</summary>
        /// <param name="Error">Возникшее исключение</param>
        public OnErrorEventArgs(GalaxyCoreException Error) { f_Error = Error; }
    }

}

namespace Galaxy.Core
{
    using Galaxy.Core.Events;

    public partial class CGalaxyCore : CGalaxyModule
    {
        /// <summary>Событие включения / выключения ядра</summary>
        public event OnEnableEventHandler OnEnable;
        /// <summary>Генерация события запуска/остановки ядра</summary>
        protected virtual void InvokeOnEnable()
        {
            InvokeOnEnable(null);
        }
        /// <summary>Асинхронная генерация события запуска/остановки ядра</summary>
        /// <param name="CallBack">Делегат обратного вызова завершения обработки</param>
        protected virtual void InvokeOnEnable(AsyncCallback CallBack)
        {
            InvokeOnEnable(CallBack, null);
        }
        /// <summary>Асинхронная генерация события запуска/остановки ядра</summary>
        /// <param name="CallBack">Делегат обратного вызова завершения обработки</param>
        /// <param name="object">Объект состояния</param>
        protected virtual void InvokeOnEnable(AsyncCallback CallBack, object @object)
        {
            if(OnEnable != null)
            {
                OnEnableEventArgs Arg = new OnEnableEventArgs(this);

                if(CallBack != null)
                    OnEnable.BeginInvoke(this, Arg, CallBack, @object);
                else
                    OnEnable.Invoke(this, Arg);
            }
        }

        /// <summary>Событие ошибки ядра</summary>
        public event OnErrorEventHandler OnError;

        /// <summary>Генерация события ошибки ядра</summary>
        /// <param name="Error">Исключительная ситуация ядра</param>
        protected virtual void InvokeOnError(GalaxyCoreException Error)
        {
            InvokeOnError(Error, null);
        }
        /// <summary>Генерация события возникновения исключительной ситуации в ядре</summary>
        /// <param name="Error">Исключение ядра</param>
        /// <param name="CallBack">Делегат обратного вызова окончания обработки</param>
        protected virtual void InvokeOnError(GalaxyCoreException Error,
            AsyncCallback CallBack)
        {
            InvokeOnError(Error, CallBack, null);
        }
        /// <summary>Генерация события возникновения исключительной ситуации в ядре</summary>
        /// <param name="Error">Исключение ядра</param>
        /// <param name="CallBack">Делегат обратного вызова окончания обработки</param>
        /// <param name="object">Объект состояния</param>
        protected virtual void InvokeOnError(GalaxyCoreException Error,
            AsyncCallback CallBack, object @object)
        {
            if(OnError != null)
            {
                OnErrorEventArgs Arg = new OnErrorEventArgs(Error);
                if(CallBack != null)
                    OnError.BeginInvoke(this, Arg, CallBack, @object);
                else OnError.Invoke(this, Arg);
            }
        }

    }

    //public partial class CopyOfCGalaxyCore : CGalaxyModule
    //{
    //    /// <summary>Событие включения / выключения ядра</summary>
    //    public event OnEnableEventHandler OnEnable;
    //    /// <summary>Генерация события запуска/остановки ядра</summary>
    //    protected virtual void InvokeOnEnable()
    //    {
    //        InvokeOnEnable(null);
    //    }
    //    /// <summary>Асинхронная генерация события запуска/остановки ядра</summary>
    //    /// <param name="CallBack">Делегат обратного вызова завершения обработки</param>
    //    protected virtual void InvokeOnEnable(AsyncCallback CallBack)
    //    {
    //        InvokeOnEnable(CallBack, null);
    //    }
    //    /// <summary>Асинхронная генерация события запуска/остановки ядра</summary>
    //    /// <param name="CallBack">Делегат обратного вызова завершения обработки</param>
    //    /// <param name="object">Объект состояния</param>
    //    protected virtual void InvokeOnEnable(AsyncCallback CallBack, object @object)
    //    {
    //        if(OnEnable != null)
    //        {
    //            OnEnableEventArgs Arg = new OnEnableEventArgs(this);

    //            if(CallBack != null)
    //                OnEnable.BeginInvoke(this, Arg, CallBack, @object);
    //            else
    //                OnEnable.Invoke(this, Arg);
    //        }
    //    }

    //    /// <summary>Событие ошибки ядра</summary>
    //    public event OnErrorEventHandler OnError;

    //    /// <summary>Генерация события ошибки ядра</summary>
    //    /// <param name="Error">Исключительная ситуация ядра</param>
    //    protected virtual void InvokeOnError(GalaxyCoreException Error)
    //    {
    //        InvokeOnError(Error, null);
    //    }
    //    /// <summary>Генерация события возникновения исключительной ситуации в ядре</summary>
    //    /// <param name="Error">Исключение ядра</param>
    //    /// <param name="CallBack">Делегат обратного вызова окончания обработки</param>
    //    protected virtual void InvokeOnError(GalaxyCoreException Error,
    //        AsyncCallback CallBack)
    //    {
    //        InvokeOnError(Error, CallBack, null);
    //    }
    //    /// <summary>Генерация события возникновения исключительной ситуации в ядре</summary>
    //    /// <param name="Error">Исключение ядра</param>
    //    /// <param name="CallBack">Делегат обратного вызова окончания обработки</param>
    //    /// <param name="object">Объект состояния</param>
    //    protected virtual void InvokeOnError(GalaxyCoreException Error,
    //        AsyncCallback CallBack, object @object)
    //    {
    //        if(OnError != null)
    //        {
    //            OnErrorEventArgs Arg = new OnErrorEventArgs(Error);
    //            if(CallBack != null)
    //                OnError.BeginInvoke(this, Arg, CallBack, @object);
    //            else OnError.Invoke(this, Arg);
    //        }
    //    }

    //}
}
